from .universal_ast_nodes import *


class UASTTypeExtractor:
    def __init__(self, file_uast: CompilationUnit) -> None:
        self.file_uast = file_uast
        self.type_uasts: Dict[str, Union[StructDecl, Type]] = {}

    def extract_struct_decl(self, node: StructDecl) -> None:
        self.type_uasts[node.name] = node

    # def get_struct_def(self, root_type_ref: TypeRef):
    #     match root_type_ref:
    #         case AddrReferenceType():
    #             return self.get_struct_def(root_type_ref.referee)
    #         case TypeRef():
    #             type_name = root_type_ref.name
    #             # raise NotImplementedError("这还需要再修改！", root_type_ref.name)
    #             # 在以下条件下，需要直接返回类型
    #             # if remove_whitespace_and_duplicates(type_name).issubset( {"typedef", "int", "float", "double", "long", "unsigned", "signed", "struct", "union", "enum"}):
    #             #     return BuiltinType(type_name)
    #             # if type_name.find("(")!=-1 and type_name.find(")")!=-1:
    #             #     return AddrReferenceType(MethodType([UnknownType("unknown type ame for method")], []))
    #             if type_name.startswith("enum"):
    #                 return UnknownType("enum ....")
    #             # print(type_name)
    #             if type_name.startswith(("struct ", "volatile struct", "const struct")):
    #                 type_name = self.remove_struct_prefix(type_name)
    #                 return (
    #                     self.file_uast.filter_by(StructDecl, name=type_name)
    #                     .filter(lambda stru: stru.members)
    #                     .head()
    #                 )
    #             else:
    #                 try:
    #                     typedef_uast: Type = self.file_uast.filter_by(
    #                         (Type,), name=type_name
    #                     ).head()
    #                 except StopIteration as e:
    #                     print("type_name", type_name)
    #                     raise e
    #                 return self.parse_typedef(typedef_uast)
    #         case VoidType() | IntType() | FloatType():
    #             raise InvalidTypeError()
    #         case MethodType():
    #             return root_type_ref
    #         case _:
    #             raise NotImplementedError(root_type_ref)

    def parse_typedef(self, typedef_uast: Type) -> BaseType:
        self.type_uasts[typedef_uast.name] = typedef_uast

    def extract(self) -> None:
        for node in self.file_uast.children:
            match node:
                case StructDecl():
                    self.extract_struct_decl(node)
                case Type():
                    self.parse_typedef(node)
